﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace Singleton
{
    internal class Program
    {
        static void Main(string[] args)
        {


            {
                ////静态类的静态对象和构造函数只有在第一次使用时实例化
                //StaticSingleton.getInstance();
                //StaticSingleton.getInstance();

            }

            //测试lock的生效范围
            {
                //lockTest test = new lockTest();
                //lockTest test1 = new lockTest();

                //lock同一实例的（静态或实例）对象，得到顺序执行结果
                //test.ObjLock();
                //test.StaticLock();

                //lock不同实例的实例对象，得到乱序结果（各实例分别抢占线程）
                //test.ObjLock();
                //test1.ObjLock();

                //lock不同实例的静态对象，得到顺序执行的结果
                //test.StaticLock();
                //test1.StaticLock();

                //lock不同对象的实例对象和静态对象，得到乱序结果。
                //test.ObjLock();
                //test1.StaticLock();
            }

            //多例
            {
                //MultiSingleton.Init(3);
                //MultiSingleton multi1= MultiSingleton.GetInstance(2);
                ////GetAddress(multi1);
                //Console.WriteLine(  multi1.id);
                //MultiSingleton multi2 = MultiSingleton.GetInstance(5);
                ////GetAddress(multi2);
                //Console.WriteLine(multi2.id);
            }

            //lazy，在使用对象时，才对对象进行初始化。
            //结果为：
            //====
            //***
            //***
            //=1====1=1=1
            {
                Lazy<lockTest> test = new Lazy<lockTest>();
                Console.WriteLine("=========");
                test.Value.GetType();
                lockTest xmlTest = new lockTest();
                Console.WriteLine("=1====1=1=1=11==");
            }
            Console.ReadKey();
        }
        public static void GetAddress(MultiSingleton obj)
        {
            GCHandle handle = GCHandle.Alloc(obj, GCHandleType.Pinned);
            IntPtr ptr = handle.AddrOfPinnedObject();
            Console.WriteLine(ptr.ToString());
        }
    }
}
